package com.itheima.app.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.FocusUser;
import com.itheima.domain.mongo.Video;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.FocusUserService;
import com.itheima.service.mongo.VideoCommentService;
import com.itheima.service.mongo.VideoService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.CommentVo;
import com.itheima.vo.PageBeanVo;
import com.itheima.vo.VideoVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class VideoManager {

    @DubboReference
    private VideoService videoService;

    @DubboReference
    private UserInfoService userInfoService;


    // 查询推荐视频
    public PageBeanVo findRecommendVideoVoByPage(Long userId, Integer pageNum, Integer pageSize) {
        // 1.查询视频分页
        PageBeanVo pageBeanVo = videoService.findRecommendVideoByPage(userId, pageNum, pageSize);
        // 2.封装vo
        // 2-1 声明voList
        List<VideoVo> voList = new ArrayList<>();
        // 2-2 获取videoList
        List<Video> videoList = (List<Video>) pageBeanVo.getItems();
        // 2-3 遍历videoList
        if (CollectionUtil.isNotEmpty(videoList)) {
            for (Video video : videoList) {
                // 查询userInfo
                UserInfo userInfo = userInfoService.findById(video.getUserId());
                // 创建vo
                VideoVo vo = new VideoVo();
                vo.setUserInfo(userInfo); // 先
                vo.setVideo(video); // 后
                // 判断当前登录人是否关注此用户
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.FOCUS_USER, userId, video.getUserId()))) {
                    vo.setHasFocus(1);
                }
                // 是否点赞
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.VIDEO_LIKE, userId, video.getId().toHexString()))) {
                    vo.setHasLiked(1);
                }
                // 添加到集合
                voList.add(vo);
            }
        }
        // 3.将voList设置到分页对象
        pageBeanVo.setItems(voList);

        // 4.返回分页对象
        return pageBeanVo;
    }

    @Autowired
    private FastFileStorageClient client;

    @Autowired
    private FdfsWebServer webServer;

    @Autowired
    private RabbitTemplate rabbitTemplate;
    // 发布视频
    public void publishVideo(Long userId, MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {
        // 1.上传封面
        StorePath storePath1 = client.uploadFile(videoThumbnail.getInputStream(), videoThumbnail.getSize(), FileUtil.extName(videoThumbnail.getOriginalFilename()), null);
        String picUrl = webServer.getWebServerUrl() + storePath1.getFullPath();
        // 2.上传视频
        StorePath storePath2 = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(), FileUtil.extName(videoFile.getOriginalFilename()), null);
        String videoUrl = webServer.getWebServerUrl() + storePath2.getFullPath();
        // 3.封装video对象
        Video video = new Video();
        video.setId(ObjectId.get());  // 视频id
        video.setCreated(System.currentTimeMillis()); // 发布时间
        video.setUserId(userId); // 发布人id
        video.setPicUrl(picUrl); // 封面
        video.setVideoUrl(videoUrl); // 视频
        //  4.调用rpc保存
        videoService.publishVideo(video);

        // 5.发送mq消息
        rabbitTemplate.convertAndSend("tanhua.video.state", video.getId().toHexString());

        // 发送视频日志行为
        mqVideoManager.sendVideo(userId,video.getId() , MQVideoManager.VIDEO_PUBLISH);

    }

    @DubboReference
    private FocusUserService focusUserService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    // 关注用户
    public void saveFocusUser(Long userId, Long focusUserId) {
        // 1.封装focusUser实体
        FocusUser focusUser = new FocusUser();
        focusUser.setCreated(System.currentTimeMillis());// 关注时间
        focusUser.setUserId(userId); // 登录人id
        focusUser.setFocusUserId(focusUserId); // 视频发布人id
        // 2.调用rpc保存
        focusUserService.saveFocusUser(focusUser);
        // 3.redis存储关注标记   focus_user:{userId}_{focuUserId}
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.FOCUS_USER, userId, focusUserId), "1");

    }

    // 取消关注
    public void removeFocusUser(Long userId, Long focusUserId) {
        // 1.调用rpc删除
        focusUserService.removeFocusUser(userId, focusUserId);
        // 2.redis移除关注标记
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.FOCUS_USER, userId, focusUserId));
    }


    @DubboReference
    private VideoCommentService videoCommentService;
    @Autowired
    private MQVideoManager mqVideoManager;

    //视频点赞
    public ResponseEntity VideoLike(String publishId) {
        // 获取线程内userId
        Long userId = UserHolder.get().getId();
        // 查视频详情
        Video video = videoService.findById(new ObjectId(publishId));
        // 封装comment
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis()); // 点赞时间
        comment.setPublishId(video.getId());// 视频id
        comment.setCommentType(1); // 点赞类型
        comment.setUserId(userId); // 登录人id
        comment.setPublishUserId(video.getUserId()); // 视频发布人发布人id

        // 调用rpd保存
        Integer likeCount = videoCommentService.saveComment(comment);

        // 向redis中存储标记
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.VIDEO_LIKE, userId, publishId), "1");

        // 发送日志行为
        mqVideoManager.sendVideo(userId, video.getId(), MQVideoManager.VIDEO_LIKE);

        // 返回点赞数量
        return ResponseEntity.ok(likeCount);
    }

    //视频取消点赞
    public ResponseEntity VideoDisLike(String publishId) {
        //通过线程获取userId
        Long id = UserHolder.get().getId();
        // 调用rpc删除
        Integer likeCount = videoCommentService.removeComment(new ObjectId(publishId), id, 1);
        // 从reids中删除点赞标记
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.VIDEO_LIKE, id, publishId));
        // 发送视频日志行为
        mqVideoManager.sendVideo(id, new ObjectId(publishId), MQVideoManager.VIDEO_DISLIKE);

        // 4.返回点赞数量
        return ResponseEntity.ok(likeCount);
    }

    //视频评论分页查询
    public ResponseEntity findVideoCommentVo(String publishId, Integer pageNum, Integer pageSize) {

        //调用rpc查询
        PageBeanVo pageBeanVo = videoCommentService.findCommentByPage(new ObjectId(publishId), 2, pageNum, pageSize);
        //声明voList
        ArrayList<CommentVo> voList = new ArrayList<>();
        //获取commentlist
        List<Comment> commentList = (List<Comment>) pageBeanVo.getItems();
        //  遍历commentList
        if (CollectionUtil.isNotEmpty(commentList)) {
            for (Comment comment : commentList) {
                // 查userInfo
                UserInfo userInfo = userInfoService.findById(comment.getUserId());
                // 封装vo
                CommentVo vo = new CommentVo();
                vo.setId(comment.getId().toHexString());
                vo.setAvatar(userInfo.getAvatar());
                vo.setNickname(userInfo.getNickname());
                vo.setContent(comment.getContent());
                vo.setLikeCount(comment.getLikeCount());
                vo.setCreateDate(DateUtil.formatDateTime(new Date(comment.getCreated())));
                // 是否点赞
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.VIDEO_LIKE, UserHolder.get().getId(), comment.getId().toHexString()))) {
                    vo.setHasLiked(1);
                }
                // 添加到集合
                voList.add(vo);
            }

        }
        // 将voList设置分页对象
        pageBeanVo.setItems(voList);


        // 返回分页对象
        return ResponseEntity.ok(pageBeanVo);
    }
//视频评论发布
    public ResponseEntity videoComment(String publishId, String content) {
        // 获取线程内userId
        Long userId = UserHolder.get().getId();
        // 查询视频详情
      Video video = videoService.findById(new ObjectId(publishId));
        // 封装comment
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis()); // 评论时间
        comment.setPublishId(video.getId());// 视频id
        comment.setCommentType(2);// 动态评论类型
        comment.setUserId(userId); // 登录人id
        comment.setPublishUserId(video.getUserId());// 视频发布人id
        comment.setContent(content); // 评论 内容
        // 调用 rpc保存
        Integer commentCount = videoCommentService.saveComment(comment);
        // 返回评论数量
        // 发送视频日志行为
        mqVideoManager.sendVideo(userId, new ObjectId(publishId), MQVideoManager.VIDEO_PUBLISHPL);
        return ResponseEntity.ok(commentCount);
    }
//视频评论点赞
    public ResponseEntity videoCommentLike(String publishId) {
        //线程id
        Long userid = UserHolder.get().getId();
        //查询
        Comment comment = videoCommentService.findById(new ObjectId(publishId));

        comment.setCommentType(2);
        comment.setCreated(System.currentTimeMillis()); // 点赞时间
        comment.setUserId(userid); // 登录人id
        Integer likeCount = videoCommentService.saveComment(comment);
        // 向redis中存储标记
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.VIDEO_LIKE, userid, publishId), "1");

        // 发送视频日志行为
        mqVideoManager.sendVideo(userid,comment.getPublishId(), MQVideoManager.VIDEO_LIKECOMMENT);


        // 返回点赞数量
        return ResponseEntity.ok(likeCount);


    }
//视频评论取消点赞
    public ResponseEntity VideoCommentDisLike(String publishId) {
        //通过线程获取userId
        Long id = UserHolder.get().getId();
        // 调用rpc删除
        Integer likeCount = videoCommentService.removeComment(new ObjectId(publishId), id, 2);
        // 从reids中删除点赞标记
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.VIDEO_LIKE, id, publishId));
        Comment comment = videoCommentService.findById(new ObjectId(publishId));
        // 发送视频日志行为
        mqVideoManager.sendVideo(id,comment.getPublishId(), MQVideoManager.VIDEO_LIKECOMMENT);

        // 4.返回点赞数量
        return ResponseEntity.ok(likeCount);
    }
}
